#
#   hud.py
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; version 2 of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   Copyright
#   Author: Salvatore S. Gionfriddo
#   Contributors: Nicholas F. Hoover
#   Created: 2007.06.28
#   Last Modified: 2007.07.24
#

import pygame
import os
from EvilGreg import EvilGreg

#This class holds all of the components of the heads up display
class HUD:
    def __init__(self, screen):
        self.fps = label(screen, (10,10), "FPS:")
        self.health_bar = status_bar(screen, (100,18))
        self.health_bar.setText("Health")
        self.hunger_bar = ranged_status_bar(screen, (250,18))
        self.hunger_bar.setText("Hungry")
        self.gas_bar = status_bar(screen, (400, 18))
        self.gas_bar.setText("Gas")
        self.totalKills = label(screen, (575,10), "Total Kills:")
        self.levelKills = label(screen, (575,25), "Level Kills:")
        self.heartBurn = label(screen, (255, 42), "- - - -")
        self.heartBurn.setTextColor((255,0,0))
        
        self.hunger_bar.addRange(EvilGreg.STARVATION_MIN, EvilGreg.STARVATION_MAX,"Starving",(255,0,0))
        self.hunger_bar.addRange(EvilGreg.STARVATION_MAX + 1, EvilGreg.HEARTBURN_END - 1,"Hungry",(230,180,50))
        self.hunger_bar.addRange(EvilGreg.HEARTBURN_END, EvilGreg.HEARTBURN_MIN - 1, "Almost Full", (255,255,0))
        self.hunger_bar.addRange(EvilGreg.HEARTBURN_MIN,EvilGreg.MAX_HUNGER,"Full",(0,255,0))
        self.fps_on = True
        
        self.goal = text_box(screen, (575,45), ["Goal:"])
        self.health_bar.setAlpha(200)
        self.hunger_bar.setAlpha(200)
        self.gas_bar.setAlpha(200)
        self.heartBurn.setAlpha(200)
        self.goal.setAlpha(200)
        self.reset()

    def reset(self):
        self.health_bar.setValue(EvilGreg.MAX_HEALTH)
        self.hunger_bar.setValue(EvilGreg.START_HUNGER)
        self.gas_bar.setValue(EvilGreg.MIN_GAS)
        self.totalKills.setValue("Total Kills:")
        self.levelKills.setValue("Level Kills")
        self.heartBurn.setValue("- - - -")
        self.goal.setValue(["Goal:"])
        
    def update(self, totalKills, levelKills, health, hunger, heartBurn, gas, goal_status, fps):
        self.updateGoal(goal_status)
        self.updateTotalKills(totalKills)
        self.updateLevelKills(levelKills)
        self.updateFPS(fps)
        self.updateHealth(health)
        self.updateHunger(hunger)
        self.updateHeartBurn(heartBurn)
        self.updateGas(gas)
        
    def updateHeartBurn(self, heartBurn):
        if heartBurn: self.heartBurn.setValue("HEARTBURN")
        else: self.heartBurn.setValue("- - - -")
    def updateGoal(self, goal_status):
        for i in range(len(goal_status)):
            goal_status[i] = "Goal: " + str(goal_status[i][0]) + " " + goal_status[i][1]
        self.goal.setValue(goal_status)
    def updateTotalKills(self, kills):
        self.totalKills.setValue("Total Kills: " + str(kills))
    def updateLevelKills(self, kills):
        self.levelKills.setValue("Level Kills: " + str(kills))
    def updateFPS(self, fps):
        self.fps.setValue("FPS: " + str(fps)[0:4])
    def updateHealth(self, health):
        self.health_bar.setValue(health)
    def updateHunger(self, hunger):
        self.hunger_bar.setValue(hunger)
    def updateGas(self, gas):
        self.gas_bar.setValue(gas)
        
    def draw(self):
        self.health_bar.draw()
        self.hunger_bar.draw()
        self.gas_bar.draw()
        if self.fps_on:
            self.fps.draw()
        self.totalKills.draw()
        self.levelKills.draw()
        self.goal.draw()
        self.heartBurn.draw()
        
    def toggleFPS(self):
        self.fps_on = not self.fps_on

#this is a base class for gui components
class widget:
    def __init__(self, screen, pos):
        self.screen = screen
        self.position = pos #(x,y)
        
class Background(widget):
    BACKGROUND_COLOR = (100,160,100) #mid-dark green
    def __init__(self, screen, pos, size, background_color = BACKGROUND_COLOR):
        widget.__init__(self, screen, pos)
        self.background_color = background_color
        self.background = pygame.Surface(size)
        self.background = self.background.convert()
        self.background.fill(self.background_color)

    def draw(self):
        self.screen.blit(self.background,self.position)
    
#static text components
class label(widget):
    def __init__(self, screen, pos, text=""):
        widget.__init__(self, screen, pos)
        self.textColor = (0,0,0)
        self.size = 14
        self.text = text
        self.show_background = False
        self.backColor = None
        self.font = pygame.font.Font(os.path.join('data','fonts','Vera.ttf'),self.size)
        self.alpha = 255
        self.render()
        
    def render(self):
        if self.backColor != None:
            self.rendered_text = self.font.render(self.text,1,self.textColor, self.backColor)
        else:
            self.rendered_text = self.font.render(self.text,1,self.textColor)

        self.rendered_rect = self.rendered_text.get_rect()
        self.rendered_text.set_alpha(self.alpha)
        self.reRender = False
        
    def draw(self):
        if self.reRender:
            self.render()
        self.screen.blit(self.rendered_text, self.position)
        
    def setValue(self, text):
        if self.text != text:
            self.text = text
            self.reRender = True
        
    def setTextColor(self, color):
        self.textColor = color
        self.reRender = True
    def setBackColor(self, color):
        self.backColor = color
        self.reRender = True
    def setAlpha(self, alpha):
        self.alpha = alpha
        self.reRender = True
    def setPosition(self, position):
        self.position = position
        self.reRender = True
    def setSize(self, size):
        self.size = size
        self.font = pygame.font.Font(os.path.join('data','fonts','Vera.ttf'),self.size)
        self.reRender = True


    
class text_box(widget):
    def __init__(self, screen, pos, strings):
        widget.__init__(self, screen, pos)
        self.strings = strings
        self.textColor = (0,0,0)
        self.fontSize = 14
        self.backColor = (200,200,200)
        self.alpha = 255
        self.render()
        
    def render(self):
        stringLabels = []
        in_box_rect = pygame.Rect(0,0,0,0)
        out_box_rect = pygame.Rect(0,0,0,0)
        
        labelYPos = 0
        for string in self.strings:
            newLabel = label(self.screen,(1,labelYPos), string)
            newLabel.setTextColor(self.textColor)
            newLabel.setSize(self.fontSize)
            if newLabel.rendered_rect.width > in_box_rect.width:
                in_box_rect.width = newLabel.rendered_rect.width
            stringLabels.append(newLabel)
            labelYPos += 20

        in_box_rect.width  += 4
        in_box_rect.height = (len(stringLabels)) * 20 + 2

        out_box_rect.width  = in_box_rect.width + 4
        out_box_rect.height = in_box_rect.height + 4

        self.rendered_box = pygame.Surface(out_box_rect.size)
        self.rendered_box.fill((0,0,0))

        inBox = pygame.Surface(in_box_rect.size)
        inBox.fill(self.backColor)
        
        for aLabel in stringLabels:
            aLabel.screen = inBox
            aLabel.draw()

        self.rendered_box.blit(inBox,(1,1))            

        renderPosition = (self.position[0] - 4, self.position[1] - 4)
        self.rendered_rect = pygame.Rect(renderPosition, out_box_rect.size)
        self.rendered_box.set_alpha(self.alpha)
        self.reRender = False
        
    def draw(self):
        if self.reRender:
            self.render()
        self.screen.blit(self.rendered_box, self.rendered_rect)

    def setValue(self, text):
        if self.strings != text:
            self.strings = text
            self.reRender = True
    def setTextColor(self, color):
        self.textColor = color
        self.reRender = True
    def setBackColor(self, color):
        self.backColor = color
        self.reRender = True
    def setAlpha(self, alpha):
        self.alpha = alpha
        self.reRender = True
    def setPosition(self, position):
        self.position = position
        self.reRender = True
    def setSize(self, size):
        self.fontSize = size
        self.reRender = True
        
class status_bar(widget):
    def __init__(self, screen, pos):
        widget.__init__(self, screen, pos)
        self.amount = 100
        (x,y) = pos
        self.label = label(screen, (x, y-15))
        self.backcolor = (0,0,0)
        self.emptycolor = (255,0,0)
        self.color = (0,255,0)
        self.labelcolor = (0,0,0)
        self.alpha = 255
        
    def draw(self):
        backgroundBar = pygame.Surface((110,20))
        backgroundBar = backgroundBar.convert()
        backgroundBar.fill(self.backcolor)

        bar = pygame.Surface((self.amount, 10))
        bar = bar.convert()
        bar.fill(self.color)
        
        emptyBar = pygame.Surface((100 - self.amount,10))
        emptyBar = emptyBar.convert()
        emptyBar.fill(self.emptycolor)

        backgroundBar.blit(bar,(5,5))
        backgroundBar.blit(emptyBar,(5 + self.amount, 5))

        backgroundBar.set_alpha(self.alpha)
        self.screen.blit(backgroundBar, self.position)
        self.label.setAlpha(self.alpha)
        self.label.draw()
    def setValue(self, amount):
        if amount < 0: amount = 0
        if amount > 100: amount = 100
        self.amount = amount
    def setText(self, text):
        self.label.setValue(text)
    def setAlpha(self, alpha):
        self.alpha = alpha
        self.reRender = True
    def setColor(self, color):
        self.color = color
    def setLabelTextColor(self, color):
        self.label.setTextColor(color)

class ranged_status_bar(status_bar):
    def __init__(self, screen, pos):
        status_bar.__init__(self, screen, pos)
        self.ranges = []
        self.range_text = []
        self.range_color = []
    def setValue(self, amount):
        status_bar.setValue(self, amount)
        i = 0
        for (x,y) in self.ranges:
            if amount >= x and amount <= y:
                self.setText(self.range_text[i])
                self.setLabelTextColor(self.range_color[i])
            i+=1
    def addRange(self, minimum, maximum, text, color):
        self.ranges.append((minimum,maximum))
        self.range_text.append(text)
        self.range_color.append(color)
